 /**
 * @file i2c.c
 * @author LuoJing
 * @version 1.0
 * @date 2018-09-14
 * @brief YC i2c bus api
 * @details inlcude init,send data and receive data
 */

#include "include.h"
#include "i2c.h"


#pragma location=mem_iic_write_data_buffer_start
__no_init volatile u8_t IIC_WPtr[MAX_IICD_WRITE_LENGTH + 4] ;

#pragma location=mem_iic_read_data_buffer_start
__no_init volatile u8_t IIC_RPtr[MAX_IICD_READ_LENGTH] ;

void YC_WaitIICDone(void);

LOCAL void YC_WaitIICDone(void)
{
	while(!(REG16(ADDR_DMA_STATUS)&(1<<5)));
}


void I2C_init(I2C_InitDef* i2c_initstruct)
{

#define AUTO_DMA_AFTER_RW_BIT 		0
#define RESTART_BETWEEN_WR_BIT 	1
#define IICD_CTRL_VAL  ((1<<AUTO_DMA_AFTER_RW_BIT)|\
						(1<<RESTART_BETWEEN_WR_BIT))
						
	I2C_RegDef * I2cAdr;
	I2cAdr = (I2C_RegDef*)(ADDR_IICD_CTRL);	
	I2cAdr->Ctrl = IICD_CTRL_VAL;
	
	/*set iic clock speed*/
	I2cAdr->Scll = i2c_initstruct->I2C_ClockSpeed-1;
	I2cAdr->Sclh = i2c_initstruct->I2C_ClockSpeed;
	I2cAdr->Stsu = i2c_initstruct->I2C_ClockSpeed;
	I2cAdr->Sthd = i2c_initstruct->I2C_ClockSpeed;
	I2cAdr->Sosu = i2c_initstruct->I2C_ClockSpeed;
	I2cAdr->Dtsu = i2c_initstruct->I2C_ClockSpeed-1;

	REG16(ADDR_IICD_TXADDR) = (u16_t)IIC_WPtr;
	REG16(ADDR_IICD_RXADDR) = (u16_t)IIC_RPtr;


}

void I2C_WriteDataFromBuff(u8_t dev_addr,u32_t reg_addr,u16_t len, u8_t* pbuff)
{	

	u8_t * WPtr_temp = (u8_t *)IIC_WPtr;
	*WPtr_temp++ = (dev_addr << 0x01) & 0xff;
	if(IS_I2C_REGADDR16BITS(reg_addr))
	{	
		*WPtr_temp++ = reg_addr >> 0x08;
		*WPtr_temp++ = reg_addr & 0xff;
		xmemcpy(WPtr_temp, pbuff, len);
		REG16(ADDR_IICD_TXLEN) = len + 3;
	}
	else
	{
		*WPtr_temp++ = reg_addr & 0xff;
		xmemcpy(WPtr_temp, pbuff, len);
		REG16(ADDR_IICD_TXLEN) = len + 2;
	}
	REG16(ADDR_IICD_RXLEN) = 0;
	
	REG16(ADDR_MISC_CTRL) |= 1 << 2;	//start iic dma
	YC_WaitIICDone();	
}

void I2C_ReadDataToBuff(u8_t dev_addr, u32_t reg_addr, u16_t len, u8_t* pbuff)
{

	u8_t * WPtr_temp = (u8_t *)IIC_WPtr;
	u8_t * RPtr_temp = (u8_t *)IIC_RPtr;

	*WPtr_temp++ = (dev_addr << 0x01) & 0xff;
	if(IS_I2C_REGADDR16BITS(reg_addr))
	{	
		*WPtr_temp++ = reg_addr >> 0x08;
		*WPtr_temp++ = reg_addr & 0xff;
		REG16(ADDR_IICD_TXLEN) = 4;
	}
	else
	{
		*WPtr_temp++ = reg_addr & 0xff;
		REG16(ADDR_IICD_TXLEN) = 3;
	}
	*WPtr_temp++ = (dev_addr << 0x01) |0x01;

	REG16(ADDR_IICD_RXLEN) = len;

	REG16(ADDR_MISC_CTRL) |= 1 << 2;	//start iic dma
	YC_WaitIICDone();	

	xmemcpy(pbuff, RPtr_temp, len);
	
}

